import { IAbility, IContext, IParam, verifyNodeLinkCond, deepCopy, typeOf, UILogicParamService, UILogicParamType } from "@/core";
/**
 * {{uiLogic.logicName}}
 * 基于template/src/ui-service/\{{appEntities}}/\{{uiLogics}}-ui-logic-base.ts.hbs生成  
 * @export
 * @class {{pascalCase uiLogic.codeName}}UILogicBase
 */
export class {{pascalCase uiLogic.codeName}}UILogicBase {

    /**
     * 返回结果
     *
     * @private
     * @type {*}
     * @memberof {{pascalCase uiLogic.codeName}}UILogicBase
     */
    private result: any;

    /**
     * 行为附加参数
     *
     * @type {*}
     * @memberof {{pascalCase uiLogic.codeName}}UILogicBase
     */
    public additionalParam: IParam = {};

    /**
     * 界面逻辑上下文
     *
     * @private
     * @type {IContext}
     * @memberof {{pascalCase uiLogic.codeName}}UILogicBase
     */
    private appContext!: IContext;

    /**
     * 界面逻辑视图参数
     *
     * @private
     * @type {IParam}
     * @memberof {{pascalCase uiLogic.codeName}}UILogicBase
     */
    private viewParam!: IParam;

    /**
     * 默认逻辑处理参数名称
     *
     * @private
     * @type {string}
     * @memberof {{pascalCase uiLogic.codeName}}UILogicBase
     */
    private defaultParamName: string = '';

    /**
     * 应用上下文参数名称
     *
     * @private
     * @type {string}
     * @memberof {{pascalCase uiLogic.codeName}}UILogicBase
     */
    private navContextParamName: string = '';

    /**
     * 视图参数名称
     *
     * @private
     * @type {string}
     * @memberof {{pascalCase uiLogic.codeName}}UILogicBase
     */
    private navViewParamParamName: string = '';

    /**
     * 当前容器参数名称
     *
     * @private
     * @type {string}
     * @memberof {{pascalCase uiLogic.codeName}}UILogicBase
     */
    private activeContainerParamName: string = '';

    /**
     * 当前激活部件参数名称
     *
     * @private
     * @type {string}
     * @memberof {{pascalCase uiLogic.codeName}}UILogicBase
     */
    private activeCtrlParamName: string = '';

    /**
     * 当前激活视图对象名称
     *
     * @private
     * @type {string}
     * @memberof {{pascalCase uiLogic.codeName}}UILogicBase
     */
    private activeViewParamName: string = '';

    /**
     * 上一次调用返回参数名称
     *
     * @private
     * @type {string}
     * @memberof {{pascalCase uiLogic.codeName}}UILogicBase
     */
    private lastReturnParamName: string = '';

    /**
     * 逻辑参数Map
     *
     * @private
     * @type {Map<string, IParam>}
     * @memberof {{pascalCase uiLogic.codeName}}UILogicBase
     */
    private logicParamMap: Map<string, IParam> = new Map();

    /**
     * 绑定上一次调用返回参数
     *
     * @memberof {{pascalCase uiLogic.codeName}}UILogicBase
     */
    public bindLastReturnParam(value: any) {
        const lastReturnParam = this.logicParamMap.get(this.lastReturnParamName);
        if (lastReturnParam) {
            lastReturnParam.bind(value);
        }
    }

    /**
     * 默认逻辑处理参数
     *
     * @memberof {{pascalCase uiLogic.codeName}}UILogicBase
     */
    get defaultParam(): any {
        return this.logicParamMap.get(this.defaultParamName);
    }

    /**
     * 上下文数据（包括应用上下文和逻辑局部上下文参数）
     *
     * @readonly
     * @memberof {{pascalCase uiLogic.codeName}}UILogicBase
     */
    get context() {
        const navContextParam = this.logicParamMap.get(this.navContextParamName);
        if (navContextParam) {
            return navContextParam.getReal();
        } else {
            return this.appContext;
        }
    }

    /**
     * 视图参数数据（包括外部传入视图参数和逻辑局部视图参数）
     *
     * @readonly
     * @memberof {{pascalCase uiLogic.codeName}}UILogicBase
     */
    get viewParams() {
        const navViewParamParam = this.logicParamMap.get(this.navViewParamParamName);
        if (navViewParamParam) {
            return navViewParamParam.getReal();
        } else {
            return this.viewParam;
        }
    }

    /**
     * 获取逻辑处理参数
     *
     * @param {string} key 逻辑处理参数的codeName
     * @memberof UIActionContext
     */
    private getParam(key: string): any {
        return this.logicParamMap.get(key);
    }

   	/**
     * Creates an instance of {{pascalCase uiLogic.codeName}}UILogicBase
     * 
     * @param {IParam} [opts={}]
     * @memberof {{pascalCase uiLogic.codeName}}UILogicBase
     */
    constructor(opts: IParam = {}) { }

    /**
     * 逻辑参数模型
     *
     * @private
     * @type {any[]}
     * @memberof {{pascalCase uiLogic.codeName}}UILogicBase
     */
    private logicParamModels: any[] = [
        {{#each uiLogic.psDEUILogicParams as | logicParam | }}
        { 
            name: "{{logicParam.name}}", 
            codeName: "{{logicParam.codeName}}", 
            {{#if logicParam.default}}
            default: {{logicParam.default}}, 
            {{/if}}
            {{#if logicParam.navContextParam}}
            navContextParam: {{logicParam.navContextParam}},
            {{/if}}
            {{#if logicParam.navViewParamParam}}
            navViewParamParam: {{logicParam.navViewParamParam}},
            {{/if}}
            {{#if logicParam.activeContainerParam}}
            activeContainerParam: {{logicParam.activeContainerParam}},
            {{/if}}
            {{#if logicParam.activeCtrlParam}}
            activeCtrlParam: {{logicParam.activeCtrlParam}},
            {{/if}}
            {{#if logicParam.activeViewParam}}
            activeViewParam: {{logicParam.activeViewParam}},
            {{/if}}
            {{#if logicParam.lastReturnParam}}
            lastReturnParam: {{logicParam.lastReturnParam}},
            {{/if}}
            {{#if logicParam.applicationParam}}
            applicationParam: {{logicParam.applicationParam}},
            {{/if}}
            {{#if logicParam.simpleParam}}
            simpleParam: {{logicParam.simpleParam}},
            {{/if}}
            {{#if logicParam.entityListParam}}
            entityListParam: {{logicParam.entityListParam}},
            {{/if}}
            {{#if logicParam.simpleListParam}}
            simpleListParam: {{logicParam.simpleListParam}},
            {{/if}}
            {{#if logicParam.entityPageParam}}
            entityPageParam: {{logicParam.entityPageParam}},
            {{/if}}
            {{#if logicParam.appGlobalParam}}
            appGlobalParam: {{logicParam.appGlobalParam}},
            {{/if}}
            {{#if logicParam.routeViewSessionParam}}
            routeViewSessionParam: {{logicParam.routeViewSessionParam}},
            {{/if}}
            {{#if logicParam.viewNavDataParam}}
            viewNavDataParam: {{logicParam.viewNavDataParam}},
            {{/if}}
            {{#if logicParam.viewSessionParam}}
            viewSessionParam: {{logicParam.viewSessionParam}},
            {{/if}}
            {{#if logicParam.filterParam}}
            filterParam: {{logicParam.filterParam}},
            {{/if}}
            {{#if logicParam.ctrlParam}}
            ctrlParam: {{logicParam.ctrlParam}},
            {{/if}}
            {{#if logicParam.entityParam}}
            entityParam: {{logicParam.entityParam}},
            {{/if}}
            {{#if logicParam.paramFieldName}}
            paramFieldName: "{{logicParam.paramFieldName}}",
            {{/if}}
        }{{#unless @last}},{{/unless}}
        {{/each}}
    ]

    /**
    * 初始化逻辑参数
    * @param context 应用上下文 
    * @param viewParams 视图参数
    * @param data 业务数据
    * @param event 事件对象
    * @param ability 当前环境能力
	* @memberof {{pascalCase uiLogic.codeName}}UILogicBase
    */
    private initLogicParams<T extends IAbility>(context: IContext, viewParams: IParam, data: IParam, $event: MouseEvent, ability: T) {
        this.appContext = deepCopy(context);
        this.viewParam = deepCopy(viewParams);
        this.additionalParam = { data, $event, ctrl: ability.viewCtx.ctrl, actionContext: ability };
        this.logicParamModels.forEach((model: IParam) => {
            if (model.default) {
                this.defaultParamName = model.codeName;
            }
            if (model.navContextParam) {
                this.navContextParamName = model.codeName;
            }
            if (model.navViewParamParam) {
                this.navViewParamParamName = model.codeName;
            }
            if (model.activeContainerParam) {
                this.activeContainerParamName = model.codeName;
            }
            if (model.activeCtrlParam) {
                this.activeCtrlParamName = model.codeName;
            }
            if (model.activeViewParam) {
                this.activeViewParamName = model.codeName;
            }
            if (model.lastReturnParam) {
                this.lastReturnParamName = model.codeName;
            }
            const uiLogicParamInstance = UILogicParamService.getLogicParamInstance(this, model, { data, context, viewParams, $event, ctrl: ability.viewCtx.ctrl, actionContext: ability });
            this.logicParamMap.set(model.codeName, uiLogicParamInstance);
        });
    }

    /**
    * 执行界面逻辑之前
    * @param context 应用上下文 
    * @param viewParams 视图参数
    * @param data 业务数据
    * @param event 事件对象
    * @param ability 当前环境能力
	* @memberof {{pascalCase uiLogic.codeName}}UILogicBase
    */
    private beforeExecute<T extends IAbility>(context: IContext, viewParams: IParam, data: IParam, event: MouseEvent, ability: T) {
        this.initLogicParams(context, viewParams, data, event, ability);
    }

    /**
    * 执行界面逻辑
    * @param context 应用上下文 
    * @param viewParams 视图参数
    * @param data 业务数据
    * @param event 事件对象
    * @param ability 当前环境能力
	* @memberof {{pascalCase uiLogic.codeName}}UILogicBase
    */
    public async execute<T extends IAbility>(context: IContext, viewParams: IParam, data: IParam, event: MouseEvent, ability: T) {
        try {
            this.beforeExecute(context, viewParams, data, event, ability);
            {{#if uiLogic.startPSDEUILogicNode}}
            await this.execute_{{uiLogic.startPSDEUILogicNode.codeName}}_node();
            {{else}}
            throw new Error('没有开始节点');
            {{/if}}
            return this.result;
        } catch (error: any) {
            throw new Error(`${error && error.message ? error.message : '发生未知错误！'}`);
        }
    }
    {{#each uiLogic.psDEUILogicNodes as | logicNode |}}
    
    {{> @macro/logic-node/include-logic-node.hbs type=logicNode.logicNodeType logicNode=logicNode uiLogic=uiLogic}}
    {{/each}}

}
